﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Xml;
using Helper;
using HtmlAgilityPack;
using Kindle.Data;

namespace Kindle.Web
{
    public partial class Default : Page
    {
        public string FeddPath { set; get; }
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        private Encoding SetEncode()
        {
            return Encoding.Default;
        }

        private MemoryStream GetHtml(string URI)
        {
            var webClient = new WebClient();
            var data = webClient.DownloadData(URI);
            var memoryStream = new MemoryStream(data);
            return memoryStream;
        }

        public void GetContentAgility(feeds item)
        {
            var doc = new HtmlDocument();
            doc.Load(GetHtml(item.feed_url), SetEncode());
            FeddPath = item.feed_url.Replace("http://", string.Empty).Replace("/", string.Empty).Replace(".", string.Empty);
            if (doc.DocumentNode != null)
            {
                var coll = doc.DocumentNode.SelectNodes("//div[contains(@class, '" + item.feed_link_class + "')]//h1//a[@href]");
                if (coll != null && coll.Count > 0)
                {
                    foreach (var li in coll)
                    {
                        GetNews(item, li.Attributes["href"].Value);
                    }
                }
            }
        }

        public void GetNews(feeds item, string s)
        {
            var doc = new HtmlDocument();
            try
            {
                string link;
                if (!s.StartsWith("http"))
                {
                    if (item.news_link_cut == string.Empty)
                    {
                        link = item.feed_url.TrimEnd('/') + s;
                    }
                    else
                    {
                        link = item.feed_url.Replace("/" + item.news_link_cut + "/", string.Empty) + s;
                    }
                }
                else
                {
                    link = s;
                }

                doc.Load(GetHtml(link), SetEncode());
                var containerNews = item.feed_news_container_class;
                var imageClass = item.feed_news_img_class;
                var bodyClass = item.feed_news_body_class;

                if (doc.DocumentNode != null)
                {
                    var coll = doc.DocumentNode.SelectNodes("//li[@id = '" + containerNews + "']");
                    if (coll != null && coll.Count > 0)
                    {
                        var ent = new kindleEntities();
                        var existingNews = ent.news.FirstOrDefault(i => i.link == link);
                        if (existingNews != null)
                        {
                            return;
                        }
                        foreach (var li in coll)
                        {
                            var newNews = new news();
                            var title = li.Element("h1").InnerText;
                            newNews.title = title;
                            newNews.id_feed = item.id_feed;
                            const string pattern = @"\/[0-9]{4}\/[0-9]{2}\/[0-9]{2}\/";
                            var rgx = new Regex(pattern, RegexOptions.IgnoreCase);
                            var matches = rgx.Matches(link);
                            if (matches.Count > 0)
                            {

                                DateTime dateValue;
                                if (DateTime.TryParseExact(matches[0].Value, "/yyyy/MM/dd/", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateValue)) ;
                                newNews.date = dateValue;
                            }
                            newNews.link = link;

                            var image = li.SelectNodes("//div[@class = '" + imageClass + "']//img[@src]");
                            if (image != null && image.Count > 0)
                            {
                                foreach (var item1 in image)
                                {
                                    var imageSrc = item1.Attributes["src"].Value;

                                    newNews.image = imageSrc.Substring(imageSrc.LastIndexOf("/", StringComparison.Ordinal) + 1,
                                                                       imageSrc.Length - imageSrc.LastIndexOf("/", StringComparison.Ordinal) - 1);
                                    ResizeImage(imageSrc, newNews.image);
                                }
                            }
                            var bodytext = li.SelectNodes("//div[@class = '" + bodyClass + "']");
                            if (bodytext != null && bodytext.Count > 0)
                            {
                                foreach (var item1 in bodytext)
                                {
                                    var allBodyImages = item1.SelectNodes("//div[@class = '" + bodyClass + "']//img[@src]");
                                    if (allBodyImages != null && allBodyImages.Count > 0)
                                    {
                                        foreach (var item2 in allBodyImages)
                                        {
                                            var imageSrc = item2.Attributes["src"].Value;

                                            item2.Attributes["src"].Value = imageSrc.Substring(imageSrc.LastIndexOf("/", StringComparison.Ordinal) + 1,
                                                                               imageSrc.Length - imageSrc.LastIndexOf("/", StringComparison.Ordinal) - 1);
                                            ResizeImage(imageSrc, item2.Attributes["src"].Value);
                                        }
                                    }
                                    RemoveUnusedElements(item1, item);
                                    var bodyText = item1.InnerHtml;
                                    newNews.body = bodyText;
                                }
                            }

                            ent.news.Add(newNews);
                            ent.SaveChanges();
                        }
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        public Bitmap GrayScale(Bitmap Bmp)
        {
            for (var y = 0; y < Bmp.Height; y++)
                for (var x = 0; x < Bmp.Width; x++)
                {
                    var c = Bmp.GetPixel(x, y);
                    var rgb = (c.R + c.G + c.B) / 3;
                    Bmp.SetPixel(x, y, Color.FromArgb(rgb, rgb, rgb));
                }
            return Bmp;
        }

        public void ResizeImage(string imagePath, string imageName)
        {
            Image image = new Bitmap(1, 1);
            var thumbnailGraph = Graphics.FromImage(image);
            var thumbnailBitmap = new Bitmap(1, 1);
            try
            {
                if (imageName.EndsWith("gif"))
                {
                    return;
                }
                var objWebClient = new WebClient();

                objWebClient.DownloadFile(imagePath, HttpContext.Current.Server.MapPath(imageName));
                image = Image.FromFile(HttpContext.Current.Server.MapPath(imageName));
                if (image.RawFormat.Equals(ImageFormat.Jpeg) || image.RawFormat.Equals(ImageFormat.Png))
                {
                    const int newwidthimg = 320;

                    var AspectRatio = image.Size.Width / (float)image.Size.Height;
                    var newHeight = Convert.ToInt32(newwidthimg / AspectRatio);

                    if (image.Size.Width > newwidthimg)
                    {
                        thumbnailBitmap = new Bitmap(image, newwidthimg, newHeight);
                    }
                    else
                    {
                        thumbnailBitmap = new Bitmap(image);
                    }
                    thumbnailGraph = Graphics.FromImage(GrayScale(thumbnailBitmap));
                    thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality;
                    thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;
                    thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;

                    var imageRectangle = new Rectangle(0, 0, newwidthimg, newHeight);
                    thumbnailGraph.DrawImage(thumbnailBitmap, imageRectangle);
                    image.Dispose();
                    if (!Directory.Exists(HttpContext.Current.Server.MapPath(FeddPath)))
                    {
                        Directory.CreateDirectory(HttpContext.Current.Server.MapPath(FeddPath));
                    }
                    thumbnailBitmap.Save(HttpContext.Current.Server.MapPath(FeddPath + "\\" + imageName), ImageFormat.Jpeg);
                }
                objWebClient.Dispose();
            }

            catch (ExternalException ex)
            {
            }

            finally
            {
                thumbnailGraph.Dispose();
                thumbnailBitmap.Dispose();
                image.Dispose();
            }
        }


        public void RemoveUnusedElements(HtmlNode item1, feeds feedItem)
        {
            var unusedElements = feedItem.exclude_element_types.Split(';');
            foreach (var item in unusedElements)
            {
                var images = item1.SelectNodes("//" + item);
                if (item == "img")
                {
                    var images3 = item1.SelectNodes("//" + item + "[@src]");
                    if (images3 != null && images3.Count > 0)
                    {
                        foreach (var image1 in images3)
                        {
                            var image3 = image1.Attributes["src"].Value;
                            foreach (var item4 in feedItem.exlude_image_types.Split(';'))
                                if (image3.EndsWith(item4))
                                {
                                    image1.ParentNode.RemoveChild(image1, false);
                                }
                        }
                    }
                }
                else
                {

                    if (images != null && images.Count > 0)
                    {
                        foreach (var image1 in images)
                        {
                            image1.ParentNode.RemoveChild(image1, false);
                        }
                    }
                }
            }
        }

        protected void btnCreateHTML_Click(object sender, EventArgs e)
        {
            var ent = new kindleEntities();
            foreach (var feed in ent.feeds)
            {
                var doc = new HtmlDocument();
                var theHtml = doc.CreateElement("html");
                var theBody = doc.CreateElement("body");
                var header = doc.CreateElement("head");
                var style = doc.CreateElement("style");
                style.InnerHtml = "P { page-break-after: always }";
                header.AppendChild(style);
                var meta = doc.CreateElement("meta");

                meta.Attributes.Add("http-equiv", "Content-Type");
                meta.Attributes.Add("content", "text/html; charset=iso-8859-1");
                header.AppendChild(meta);

                var meta1 = doc.CreateElement("meta");

                meta1.Attributes.Add("name", "GENERATOR");
                meta1.Attributes.Add("content", "Mozilla/4.8 [en] (Windows NT 5.0; U) [Netscape]");
                header.AppendChild(meta1);

                var meta2 = doc.CreateElement("meta");

                meta2.Attributes.Add("name", "Author");
                meta2.Attributes.Add("content", "Pronto");
                header.AppendChild(meta2);

                var theP = doc.CreateElement("p");
                theP.InnerHtml = "Naslovna strana na knigata";
                theBody.AppendChild(theP);

                theP = doc.CreateElement("p");
                var guide = doc.CreateElement("guide");
                var reference = doc.CreateElement("reference");

                reference.Attributes.Add("type", "toc");
                reference.Attributes.Add("title", "Table of Contents");
                reference.Attributes.Add("href", "#tocloc");
                guide.AppendChild(reference);
                theP.AppendChild(guide);

                var a = doc.CreateElement("a");
                a.Attributes.Add("name", "tocloc");
                theP.AppendChild(a);

                var h3 = doc.CreateElement("h3");
                h3.InnerHtml = "Sodrzina";

                theP.AppendChild(h3);
                var divToc = doc.CreateElement("div");
                divToc.Attributes.Add("name", "toc");
                var div = doc.CreateElement("div");
                div.Attributes.Add("align", "left");


                foreach (var item in ent.news.Where(i => i.id_feed == feed.id_feed))
                {
                    a = doc.CreateElement("a");
                    a.Attributes.Add("href", "#" + item.title);
                    a.InnerHtml = item.title;

                    var br = doc.CreateElement("br");

                    div.AppendChild(a);
                    div.AppendChild(br);
                    br = doc.CreateElement("br");
                    div.AppendChild(br);
                }

                divToc.AppendChild(div);
                theP.AppendChild(divToc);
                theBody.AppendChild(theP);
                var k = 0;
                foreach (var item in ent.news.Where(i => i.id_feed == feed.id_feed))
                {
                    theP = doc.CreateElement("p");

                    if (k == 0)
                    {
                        theP.Attributes.Add("id", "start");
                    }

                    k++;
                    theP.InnerHtml = " ";
                    theBody.AppendChild(theP);
                    a = doc.CreateElement("a");
                    a.Attributes.Add("name", item.title);
                    var h2 = doc.CreateElement("h2");
                    h2.InnerHtml = item.title;
                    var theImg = doc.CreateElement("img");
                    if (!string.IsNullOrEmpty(item.image))
                    {
                        theImg.Attributes.Add("src", item.image);
                    }

                    var thespan = doc.CreateElement("span");

                    thespan.InnerHtml = item.body.Replace("<p>", "<div>").Replace("</p>", "</div>");
                    theBody.AppendChild(a);
                    theBody.AppendChild(h2);

                    if (!string.IsNullOrEmpty(item.image))
                    {
                        theBody.AppendChild(theImg);
                    }
                    theBody.AppendChild(thespan);
                }

                var theTitle = doc.CreateElement("title");
                theTitle.InnerHtml = "Ime na Vesnikot";
                header.AppendChild(theTitle);

                theHtml.AppendChild(header);
                theHtml.AppendChild(theBody);

                // write text, no indent :(
                var feedHtmlName = feed.feed_url.Replace("http://", string.Empty).Replace("/", string.Empty).Replace(".", string.Empty);
                var feedHtmlNameANDExtension = feed.feed_url.Replace("http://", string.Empty).Replace("/", string.Empty).Replace(".", string.Empty) + ".html";
                var feedHtmlPathAndName = HttpContext.Current.Server.MapPath(feedHtmlName + "\\" + feedHtmlNameANDExtension);
                using (var sw = new StreamWriter(feedHtmlNameANDExtension, false, SetEncode()))
                {
                    theHtml.WriteTo(sw);
                }

                // write xml, nicely indented but it's XML!
                var settings = new XmlWriterSettings();
                settings.OmitXmlDeclaration = true;
                settings.Indent = true;
                settings.ConformanceLevel = ConformanceLevel.Fragment;
                settings.Encoding = SetEncode();
                using (var xw = XmlWriter.Create(feedHtmlPathAndName, settings))
                {
                    theHtml.WriteTo(xw);
                }

                var htmlDoc = new HtmlDocument();

                htmlDoc.Load(feedHtmlPathAndName,SetEncode());

                var hcn = htmlDoc.CreateComment("<!DOCTYPE html PUBLIC \"-//w3c//dtd html 4.0 transitional//en\">");

                var htmlNode = htmlDoc.DocumentNode.SelectSingleNode("/html");
                htmlDoc.DocumentNode.InsertBefore(hcn, htmlNode);

                htmlDoc.Save(feedHtmlPathAndName, SetEncode());
            }
        }

        protected void btnCreateMOBI_Click(object sender, EventArgs e)
        {
            Base.Base.LaunchCommandLineApp("wwwlefigarofrinternational");
        }

        protected void btnSendMOBI_Click(object sender, EventArgs e)
        {
            var mail = new MailHelper();
            mail.fromMail = "***@gmail.com";
            mail.toMail = "***@kindle.com";
            mail.fromName = "Pronto";
            mail.fromPassword = "***";
            mail.subject = "Le Figaro";
            var path = "wwwlefigarofrinternational";
            mail.attachment = HttpContext.Current.Server.MapPath(path) + "\\" + path + ".mobi";
            mail.Send();
        }

        protected void btnReadToDB_Click(object sender, EventArgs e)
        {
            var ent = new kindleEntities();
            foreach (var item in ent.feeds)
            {
                GetContentAgility(item);
            }
        }
    }
}